﻿#include "tk_thread.h"
#include <QtDebug>

namespace tk
{

TkThread::TkThread(QObject *parent) : QObject(parent)
{
    m_pthread = TK_NULL_PTR;
}

TkThread::~TkThread()
{
    TkMutexLocker locker(m_mutex);

    Exit();
    if(m_pthread)
    {
        delete m_pthread;
        m_pthread = TK_NULL_PTR;
    }
}

tk_bool TkThread::Start(QThread::Priority priority)
{
    TkMutexLocker locker(m_mutex);
    if(TK_NULL_PTR == m_pthread)
    {
        m_pthread = new QThread();

        connect(this, SIGNAL(SignalThreadRun()), this, SLOT(ThreadFunc()));
        moveToThread(m_pthread);
    }
    else
    {
		Exit();
    }
    m_pthread->start(priority);
    emit SignalThreadRun();
    return TK_TRUE;
}

tk_bool TkThread::Exit()
{
    TkMutexLocker locker(m_mutex);
    if(m_pthread)
    {
        if(m_pthread->isFinished())
        {
            return TK_TRUE;
        }
        else
        {
            m_pthread->requestInterruption();
            m_pthread->quit();
            if(m_pthread->isRunning())
            {
                if(!m_pthread->wait(30000))
                {
                    qWarning()<<"TkThread wait finish time out!";
                    return TK_FALSE;
                }
            }
        }
    }
    return TK_TRUE;
}

tk_bool TkThread::IsRunning()
{
	if (m_pthread)
	{
		return m_pthread->isRunning();
	}
	else
	{
		return TK_FALSE;
	}
}

QThread * TkThread::GetThread()
{
    TkMutexLocker locker(m_mutex);
    return m_pthread;
}
void TkThread::ThreadFunc()
{
    emit SignalCallFunc();
}

tk_bool TkThread::IsInterruptionRequested()
{
    return QThread::currentThread()->isInterruptionRequested();
}
void TkThread::SleepSec(tk_uint32 sec)
{
    QThread::currentThread()->sleep(sec);
}

void TkThread::SleepMs(tk_uint32 ms)
{
    QThread::currentThread()->msleep(ms);
}

void TkThread::SleepUs(tk_uint32 us)
{
    QThread::currentThread()->usleep(us);
}

/*

class test : public QObject
{
    Q_OBJECT
public:
    explicit test(QObject *parent = nullptr);
    ~test(){}

signals:
public slots:
    void _ThreadRun();

private:
    TkThread * m_thread[100];
};


//=====================================================================


void test::_ThreadRun()
{
    forever
    {
        if(TkThread::IsInterruptionRequested())
        {
            return;
        }
        qDebug()<<"_ThreadRun id: "<<QThread::currentThreadId();
        TkThread::SleepMs(10);
    }
}


test::test(QObject *parent) : QObject(parent)
{

    //方法1 m_thread只创建一次
    for(int i = 0;i<100;i++)
    {
        m_thread[i] = new qt_thread();
        connect(m_thread[i],SIGNAL(EmitCallFunc()),this,SLOT(_ThreadRun()),Qt::DirectConnection);
    }
    for(int i = 0;i<1000;i++)
    {
        for(int j = 0;j<100;j++)
        {
            m_thread[j]->start(QThread::HighestPriority);
        }
        QThread::msleep(100);
        for(int j = 0;j<100;j++)
        {
            if(m_thread[j])
            {
                m_thread[j]->exit();
            }
        }
    }
    for(int i = 0;i<100;i++)
    {
        delete m_thread[i];
    }


    //方法2 每次创建 m_thread
    for(int i = 0;i<1000;i++)
    {
        param.priority = ;

        for(int j = 0;j<100;j++)
        {
            m_thread[j] = new qt_thread();
            connect(m_thread[j],SIGNAL(EmitCallFunc()),this,SLOT(_ThreadRun()),Qt::DirectConnection);
            m_thread[j]->start(QThread::HighestPriority);
        }
        QThread::msleep(1000);
        for(int j = 0;j<100;j++)
        {
            if(m_thread[j])
            {
                disconnect(m_thread[j],SIGNAL(EmitCallFunc()),this,SLOT(_ThreadRun()));
                m_thread[j]->exit();
                delete m_thread[j];
            }
        }
    }
}
*/

}//namespace tk
